﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using System.Xml;

namespace Restful.Net.Serialization
{
    public class XmlSerializer : ISerializer
    {
        public string ResponseContentType
        {
            get
            {
                return "application/xml";
            }
        }

        public bool Supports(string contentType)
        {
            switch (contentType.ToLower())
            {
                case "text/xml":
                case "text/*":
                case "application/xml":
                case "*/*":
                    return true;
                default:
                    return false;
            }
        }

        public void Serialize(object objectToserialize, Stream outputStream)
        {
            DataContractSerializer serializer = new DataContractSerializer(objectToserialize.GetType());
            serializer.WriteObject(outputStream, objectToserialize);
        }

        public object Deserialize(Type t, Stream inputStream)
        {
            Task<object> task = DeserializeAsync(t, inputStream);
            task.Wait();
            return task.Result;
        }

        public async Task<object> DeserializeAsync(Type t, Stream inputStream)
        {
            DataContractSerializer serializer = new DataContractSerializer(t);

            using (StreamReader reader = new StreamReader(inputStream))
            {
                string contents = await reader.ReadToEndAsync();
                using (TextReader textReader = new StringReader(contents))
                {
                    using (XmlReader xmlReader = XmlReader.Create(textReader))
                    {
                        return serializer.ReadObject(xmlReader);
                    }
                }
            }
        }

        public async Task SerializeAsync(object objectToSerialize, Stream outputStream)
        {
            DataContractSerializer serializer = new DataContractSerializer(objectToSerialize.GetType());

            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, objectToSerialize);

                ms.Position = 0;

                await ms.CopyToAsync(outputStream);
            }
        }
    }
}
